package com.xmg.dataStructure.tensuanfa;

import java.util.Arrays;

/**
 * 普利姆算法解决修路问题
 */
public class PrimAlgorithm {
    public static void main(String[] args) {
        char[] data = new char[]{'A','B','C','D','E','F','G'};
        int verx = data.length;
        //邻接矩阵的关系使用二维数组表示，10000表示两个点之间不连通
        int[][] weight = new int[][]{
                {10000,5,7,10000,10000,10000,2},
                {5,10000,10000,9,10000,10000,2},
                {7,10000,10000,10000,8,10000,10000},
                {10000,9,10000,10000,10000,4,10000},
                {10000,10000,8,10000,10000,5,4},
                {10000,10000,10000,4,5,10000,6},
                {2,3,10000,10000,4,6,10000}
        };

        //创建grpah对象
        MGraph graph = new MGraph(verx);
        MinTree minTree= new MinTree();
        minTree.createGraph(graph,verx,data,weight);
        minTree.showGraph(graph);

        minTree.prim(graph,0);
    }
}
//创建最小生成树->村庄的图
class MinTree{
    //创建图的邻接矩阵

    /**
     *
     * @param mGraph 图对象
     * @param verxs 图对应的节点
     * @param data  图的各个顶点的值
     * @param weight 图的邻接矩阵
     */
    public void createGraph(MGraph mGraph,int verxs,char[] data,int[][] weight){
        int i,j;
        for (i = 0; i < verxs; i++) {//顶点
            mGraph.data[i] = data[i];
            for (j = 0;j<verxs;j++){
                mGraph.weight[i][j] = weight[i][j];
            }
        }
    }

    //显示图的邻接矩阵
    public void showGraph(MGraph mGraph){
        for (int[] link:mGraph.weight) {
            System.out.println(Arrays.toString(link));
        }
    }

    //编写prim算法，得到最小生成树

    /**
     *
     * @param graph 图
     * @param v 表示从图的第几个节点开始生成
     */
    public void prim(MGraph graph,int v){
        int[] visited = new int[graph.verx];//标记节点是否被访问过
        //把当前节点标记为已访问
        visited[v] = 1;
        //h1和h2记录两个顶点的下标
        int h1 = -1;
        int h2 = -1;
        int minWeight = 10000; //将minWeight初始化成一个大数，后面会被替换
        for (int k = 1; k < graph.verx; k++) {//因为有graph.verxs个顶点，普利姆算法结束后，有graph.verxs-1条边

            for (int i = 0; i < graph.verx; i++) {
                for (int j = 0; j < graph.verx; j++) {
                    if(visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight){
                        minWeight = graph.weight[i][j];
                        h1 = i;
                        h2 = j;
                    }
                }
            }

            System.out.println("边 <" + graph.data[h1] +","+graph.data[h2]+"> 权值："+minWeight);
            visited[h2] = 1;
            minWeight = 10000;
        }
    }
}

class MGraph{
    int verx;//表示图的节点数
    char[] data;//存放节点个数
    int[][] weight;//存放边，就是我们的邻接矩阵

    public MGraph(int verx) {
        this.verx = verx;
        data = new char[verx];
        weight = new int[verx][verx];
    }
}
